﻿using MongoDB.Driver;
using Sustainalytics.Entities;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace Sustainalytics.DataLayer.Shared
{
    public interface IRepository
    {
    }

    public interface IRepositoryCollection<T> : IRepositoryCollection<T, Guid> where T : IEntity
    {
        bool DropAndCreate();

        bool CreateBatch(IEnumerable<T> obj);
        bool CreateBatchParallel(IEnumerable<T> obj, int bulkInsertSize = 1000, int maxParalelism = -1);

        bool CreateOrUpdate(T obj);

        bool CreateOrUpdateBatch(IEnumerable<T> obj);

        bool DeleteWhere(Expression<Func<T, bool>> wherePredicate);

        bool DeleteAll();

        IList<T> ReadAll();

        IList<T> ReadAll(string[] includedFields, int? skip = null, int? take = null, Ordering<T> ordering = null, bool useCollation = false);

        //IList<T> ReadAllWhere(Expression<Func<T, bool>> wherePredicate, int? skip = null, int? take = null, Ordering<T> orderBy = null);

        IList<T> ReadAllWhereFieldEqualsValue<TK>(Expression<Func<T, TK>> selectPropertyExpression, TK value, int? skip = null, int? take = null, string[] includedFields = null);

        IList<T> ReadAllWhereFieldEqualsValue<TK>(string fieldName, TK value, int? skip = null, int? take = null, string[] includedFields = null);

        long ReadCount();

        IList<T> ReadAllWhere(Expression<Func<T, bool>> wherePredicate, int? skip = null, int? take = null, Ordering<T> ordering = null, bool useCollation = false, params string[] includeFields);
        IList<T> ReadWhere(Expression<Func<T, bool>> wherePredicate, int? skip = null, int? take = null, Ordering<T> ordering = null, params Expression<Func<T, object>>[] includeFields);

        long ReadCount(Expression<Func<T, bool>> wherePredicate);


        string ToString();

        bool CollectionExists();

        IMongoCollection<T> Collection();

        string GetDatabaseName();
        string GetCollectionName();
    }

    public interface IRepositoryCollection<T, TKey> : IRepository where T : IEntity<TKey>
    {
        bool Create(T obj);

        bool Delete(TKey id);

        void Delete(IEnumerable<TKey> ids);

        bool Exists(TKey id);

        T Read(TKey id);

        IDictionary<TKey, T> ReadbyIds(IEnumerable<TKey> ids, string[] includedFields = null);

        bool Update(TKey id, T obj);

        bool Drop();

        bool CreateBatch(IEnumerable<T> toInsert);
    }
}